package com.benefitj.jpuppeteer.chromium;

import com.benefitj.jpuppeteer.Event;
import lombok.Data;

import java.util.List;

/**
 * Input Domain
 */
@ChromiumApi("Input")
public interface Input {

  /**
   * Cancels any active dragging in the page.
   */
  void cancelDragging();

  /**
   * Dispatches a key event to the page.
   *
   * @param type                  string
   *                              Type of the key event.
   *                              Allowed Values: keyDown, keyUp, rawKeyDown, char
   * @param timestamp             TimeSinceEpoch
   *                              Time at which the event occurred.
   * @param text                  string
   *                              Text as generated by processing a virtual key code with a keyboard layout. Not needed for for keyUp and rawKeyDown events (default: "")
   * @param unmodifiedText        string
   *                              Text that would have been generated by the keyboard if no modifiers were pressed (except for shift). Useful for shortcut (accelerator) key handling (default: "").
   * @param keyIdentifier         string
   *                              Unique key identifier (e.g., 'U+0041') (default: "").
   * @param code                  string
   *                              Unique DOM defined string value for each physical key (e.g., 'KeyA') (default: "").
   * @param key                   string
   *                              Unique DOM defined string value describing the meaning of the key in the context of active modifiers, keyboard layout, etc (e.g., 'AltGr') (default: "").
   * @param windowsVirtualKeyCode integer
   *                              Windows virtual key code (default: 0).
   * @param nativeVirtualKeyCode  integer
   *                              Native virtual key code (default: 0).
   * @param autoRepeat            boolean
   *                              Whether the event was generated from auto repeat (default: false).
   * @param isKeypad              boolean
   *                              Whether the event was generated from the keypad (default: false).
   * @param isSystemKey           boolean
   *                              Whether the event was a system key event (default: false).
   * @param location              integer
   *                              Whether the event was from the left or right side of the keyboard. 1=Left, 2=Right (default: 0).
   * @param commands              array[ string ]
   *                              Editing commands to send with the key event (e.g., 'selectAll') (default: []). These are related to but not equal the command names used in document.execCommand and NSStandardKeyBindingResponding. See https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/core/editing/commands/editor_command_names.h for valid command names.
   */
  void dispatchKeyEvent(String type, Integer timestamp, String text, String unmodifiedText, String keyIdentifier, String code,
                        String key, Integer windowsVirtualKeyCode, Integer nativeVirtualKeyCode, Boolean autoRepeat,
                        Boolean isKeypad, Boolean isSystemKey, Integer location, List<String> commands);

  /**
   * Dispatches a mouse event to the page.
   *
   * @param type               string
   *                           Type of the mouse event.
   *                           Allowed Values: mousePressed, mouseReleased, mouseMoved, mouseWheel
   * @param x                  number
   *                           X coordinate of the event relative to the main frame's viewport in CSS pixels.
   * @param y                  number
   *                           Y coordinate of the event relative to the main frame's viewport in CSS pixels. 0 refers to the top of the viewport and Y increases as it proceeds towards the bottom of the viewport.
   * @param modifiers          integer
   *                           Bit field representing pressed modifier keys. Alt=1, Ctrl=2, Meta/Command=4, Shift=8 (default: 0).
   * @param timestamp          TimeSinceEpoch
   *                           Time at which the event occurred.
   * @param button             MouseButton
   *                           Mouse button (default: "none").
   * @param buttons            integer
   *                           A number indicating which buttons are pressed on the mouse when a mouse event is triggered. Left=1, Right=2, Middle=4, Back=8, Forward=16, None=0.
   * @param clickCount         integer
   *                           Number of times the mouse button was clicked (default: 0).
   * @param force              number
   *                           The normalized pressure, which has a range of [0,1] (default: 0). EXPERIMENTAL
   * @param tangentialPressure number
   *                           The normalized tangential pressure, which has a range of [-1,1] (default: 0). EXPERIMENTAL
   * @param tiltX              integer
   *                           The plane angle between the Y-Z plane and the plane containing both the stylus axis and the Y axis, in degrees of the range [-90,90], a positive tiltX is to the right (default: 0). EXPERIMENTAL
   * @param tiltY              integer
   *                           The plane angle between the X-Z plane and the plane containing both the stylus axis and the X axis, in degrees of the range [-90,90], a positive tiltY is towards the user (default: 0). EXPERIMENTAL
   * @param twist              integer
   *                           The clockwise rotation of a pen stylus around its own major axis, in degrees in the range [0,359] (default: 0). EXPERIMENTAL
   * @param deltaX             number
   *                           X delta in CSS pixels for mouse wheel event (default: 0).
   * @param deltaY             number
   *                           Y delta in CSS pixels for mouse wheel event (default: 0).
   * @param pointerType        string
   *                           Pointer type (default: "mouse").
   *                           Allowed Values: mouse, pen
   */
  void dispatchMouseEvent(String type, Integer x, Integer y, Integer modifiers, Long timestamp, MouseButton button,
                          Integer buttons, Integer clickCount, Integer force, Integer tangentialPressure, Integer tiltX, Integer tiltY,
                          Integer twist, Integer deltaX, Integer deltaY, String pointerType);

  /**
   * Dispatches a touch event to the page.
   *
   * @param type        string
   *                    Type of the touch event. TouchEnd and TouchCancel must not contain any touch points, while TouchStart and TouchMove must contains at least one.
   *                    Allowed Values: touchStart, touchEnd, touchMove, touchCancel
   * @param touchPoints array[ TouchPoint ]
   *                    Active touch points on the touch device. One event per any changed point (compared to previous touch event in a sequence) is generated, emulating pressing/moving/releasing points one by one.
   * @param modifiers   integer
   *                    Bit field representing pressed modifier keys. Alt=1, Ctrl=2, Meta/Command=4, Shift=8 (default: 0).
   * @param timestamp   TimeSinceEpoch
   *                    Time at which the event occurred.
   */
  void dispatchTouchEvent(String type, List<TouchPoint> touchPoints, Integer modifiers, Long timestamp);

  /**
   * Ignores input events (useful while auditing page).
   *
   * @param ignore boolean
   *               Ignores input events processing when set to true.
   */
  void setIgnoreInputEvents(Boolean ignore);

  /**
   * Dispatches a drag event into the page.
   *
   * @param type      string
   *                  Type of the drag event.
   *                  Allowed Values: dragEnter, dragOver, drop, dragCancel
   * @param x         number
   *                  X coordinate of the event relative to the main frame's viewport in CSS pixels.
   * @param y         number
   *                  Y coordinate of the event relative to the main frame's viewport in CSS pixels. 0 refers to the top of the viewport and Y increases as it proceeds towards the bottom of the viewport.
   * @param data      DragData
   * @param modifiers integer
   *                  Bit field representing pressed modifier keys. Alt=1, Ctrl=2, Meta/Command=4, Shift=8 (default: 0).
   */
  void dispatchDragEvent(String type, Integer x, Integer y, DragData data, Integer modifiers);

  /**
   * Emulates touch event from the mouse event parameters.
   *
   * @param type       string
   *                   Type of the mouse event.
   *                   Allowed Values: mousePressed, mouseReleased, mouseMoved, mouseWheel
   * @param x          integer
   *                   X coordinate of the mouse pointer in DIP.
   * @param y          integer
   *                   Y coordinate of the mouse pointer in DIP.
   * @param button     MouseButton
   *                   Mouse button. Only "none", "left", "right" are supported.
   * @param timestamp  TimeSinceEpoch
   *                   Time at which the event occurred (default: current time).
   * @param deltaX     number
   *                   X delta in DIP for mouse wheel event (default: 0).
   * @param deltaY     number
   *                   Y delta in DIP for mouse wheel event (default: 0).
   * @param modifiers  integer
   *                   Bit field representing pressed modifier keys. Alt=1, Ctrl=2, Meta/Command=4, Shift=8 (default: 0).
   * @param clickCount integer
   *                   Number of times the mouse button was clicked (default: 0).
   */
  void emulateTouchFromMouseEvent(String type, Integer x, Integer y, MouseButton button, Long timestamp, Integer deltaX,
                                  Integer deltaY, Integer modifiers, Integer clickCount);

  /**
   * This method sets the current candidate text for ime. Use imeCommitComposition to commit the final text. Use imeSetComposition with empty string as text to cancel composition.
   *
   * @param text             string
   *                         The text to insert
   * @param selectionStart   integer
   *                         selection start
   * @param selectionEnd     integer
   *                         selection end
   * @param replacementStart integer
   *                         replacement start
   * @param replacementEnd   integer
   *                         replacement end
   */
  void imeSetComposition(String text, Integer selectionStart, Integer selectionEnd, Integer replacementStart, Integer replacementEnd);

  /**
   * This method emulates inserting text that doesn't come from a key press, for example an emoji keyboard or an IME.
   *
   * @param text string
   *             The text to insert.
   */
  void insertText(String text);

  /**
   * Prevents default drag and drop behavior and instead emits Input.dragIntercepted events. Drag and drop behavior can
   * be directly controlled via Input.dispatchDragEvent.
   *
   * @param enabled boolean
   */
  void setInterceptDrags(Boolean enabled);

  /**
   * Synthesizes a pinch gesture over a time period by issuing appropriate touch events.
   *
   * @param x                 number
   *                          X coordinate of the start of the gesture in CSS pixels.
   * @param y                 number
   *                          Y coordinate of the start of the gesture in CSS pixels.
   * @param scaleFactor       number
   *                          Relative scale factor after zooming (>1.0 zooms in, <1.0 zooms out).
   * @param relativeSpeed     integer
   *                          Relative pointer speed in pixels per second (default: 800).
   * @param gestureSourceType GestureSourceType
   *                          Which type of input events to be generated (default: 'default', which queries the platform for the preferred input type).
   */
  void synthesizePinchGesture(Integer x, Integer y, Double scaleFactor, Integer relativeSpeed, GestureSourceType gestureSourceType);

  /**
   * Synthesizes a scroll gesture over a time period by issuing appropriate touch events.
   *
   * @param x                     number
   *                              X coordinate of the start of the gesture in CSS pixels.
   * @param y                     number
   *                              Y coordinate of the start of the gesture in CSS pixels.
   * @param xDistance             number
   *                              The distance to scroll along the X axis (positive to scroll left).
   * @param yDistance             number
   *                              The distance to scroll along the Y axis (positive to scroll up).
   * @param xOverscroll           number
   *                              The number of additional pixels to scroll back along the X axis, in addition to the given distance.
   * @param yOverscroll           number
   *                              The number of additional pixels to scroll back along the Y axis, in addition to the given distance.
   * @param preventFling          boolean
   *                              Prevent fling (default: true).
   * @param speed                 integer
   *                              Swipe speed in pixels per second (default: 800).
   * @param gestureSourceType     GestureSourceType
   *                              Which type of input events to be generated (default: 'default', which queries the platform for the preferred input type).
   * @param repeatCount           integer
   *                              The number of times to repeat the gesture (default: 0).
   * @param repeatDelayMs         integer
   *                              The number of milliseconds delay between each repeat. (default: 250).
   * @param interactionMarkerName string
   *                              The name of the interaction markers to generate, if not empty (default: "").
   */
  void synthesizeScrollGesture(Integer x, Integer y, Integer xDistance, Integer yDistance, Integer xOverscroll, Integer yOverscroll, Boolean preventFling,
                               Integer speed, GestureSourceType gestureSourceType, Integer repeatCount, Long repeatDelayMs, String interactionMarkerName);

  /**
   * Synthesizes a tap gesture over a time period by issuing appropriate touch events.
   *
   * @param x                 number
   *                          X coordinate of the start of the gesture in CSS pixels.
   * @param y                 number
   *                          Y coordinate of the start of the gesture in CSS pixels.
   * @param duration          integer
   *                          Duration between touchdown and touchup events in ms (default: 50).
   * @param tapCount          integer
   *                          Number of times to perform the tap (e.g. 2 for double tap, default: 1).
   * @param gestureSourceType GestureSourceType
   *                          Which type of input events to be generated (default: 'default', which queries the platform for the preferred input type).
   */
  void synthesizeTapGesture(Integer x, Integer y, Integer duration, Integer tapCount, GestureSourceType gestureSourceType);


  @Event("Input")
  public interface Events {

    /**
     * Emitted only when Input.setInterceptDrags is enabled. Use this data with Input.dispatchDragEvent to restore normal drag and drop behavior.
     *
     * @param data DragData
     */
    @Event("dragIntercepted")
    void dragIntercepted(DragData data);

  }

  /**
   * Allowed Values: none, left, middle, right, back, forward
   */
  public enum MouseButton {
    none, left, middle, right, back, forward
  }

  /**
   *
   */
  @Data
  public class TouchPoint {
    /**
     * X coordinate of the event relative to the main frame's viewport in CSS pixels.
     */
    Integer x;
    /**
     * Y coordinate of the event relative to the main frame's viewport in CSS pixels. 0 refers to the top of the viewport and Y increases as it proceeds towards the bottom of the viewport.
     */
    Integer y;
    /**
     * X radius of the touch area (default: 1.0).
     */
    Double radiusX;
    /**
     * Y radius of the touch area (default: 1.0).
     */
    Double radiusY;
    /**
     * Rotation angle (default: 0.0).
     */
    Integer rotationAngle;
    /**
     * Force (default: 1.0).
     */
    Double force;
    /**
     * The normalized tangential pressure, which has a range of [-1,1] (default: 0). EXPERIMENTAL
     */
    Double tangentialPressure;
    /**
     * The plane angle between the Y-Z plane and the plane containing both the stylus axis and the Y axis, in degrees of the range [-90,90], a positive tiltX is to the right (default: 0) EXPERIMENTAL
     */
    Integer tiltX;
    /**
     * The plane angle between the X-Z plane and the plane containing both the stylus axis and the X axis, in degrees of the range [-90,90], a positive tiltY is towards the user (default: 0). EXPERIMENTAL
     */
    Integer tiltY;
    /**
     * The clockwise rotation of a pen stylus around its own major axis, in degrees in the range [0,359] (default: 0). EXPERIMENTAL
     */
    Integer twist;
    /**
     * Identifier used to track touch sources between events, must be unique within an event.
     */
    Integer id;
  }

  /**
   *
   */
  @Data
  public class DragData {
    /**
     * array[ DragDataItem ]
     */
    List<DragDataItem> items;
    /**
     * List of filenames that should be included when dropping
     * array[ string ]
     */
    List<String> files;
    /**
     * Bit field representing allowed drag operations. Copy = 1, Link = 2, Move = 16
     */
    Integer dragOperationsMask;
  }

  /**
   *
   */
  @Data
  public class DragDataItem {
    /**
     * Mime type of the dragged data.
     */
    String mimeType;
    /**
     * Depending of the value of mimeType, it contains the dragged link, text, HTML markup or any other data.
     */
    String data;
    /**
     * Title associated with a link. Only valid when mimeType == "text/uri-list".
     */
    String title;
    /**
     * Stores the base URL for the contained markup. Only valid when mimeType == "text/html".
     */
    String baseURL;
  }

  /**
   * Allowed Values: default, touch, mouse
   */
  public enum GestureSourceType {
    __default, touch, mouse
  }

}
